package com.zenithmind.news.service.impl;

import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.zenithmind.common.utils.BeanCopyUtils;
import com.zenithmind.news.pojo.entity.News;
import com.zenithmind.news.pojo.vo.NewsVO;
import com.zenithmind.news.service.NewsPushService;
import com.zenithmind.news.websocket.NewsWebSocketHandler;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;

import java.util.List;

/**
 * 新闻推送服务实现类 - 遵循单一职责原则
 * 专门负责新闻的实时推送功能
 * 
 * @author ZenithMind Team
 * @since 2025-01-09
 */
@Slf4j
@Service
@RequiredArgsConstructor
public class NewsPushServiceImpl implements NewsPushService {

    private final NewsWebSocketHandler newsWebSocketHandler;
    private final ObjectMapper objectMapper;

    @Override
    public Boolean pushNews(News news) {
        try {
            NewsVO newsVO = convertToVO(news);
            
            // 根据分类推送
            if (StringUtils.hasText(news.getCategoryId())) {
                pushNewsToCategory(news.getCategoryId(), news);
            }
            
            // 根据标签推送
            if (StringUtils.hasText(news.getTags())) {
                pushNewsByTags(news);
            }
            
            // 如果是紧急新闻，广播给所有用户
            if (news.getPriority() != null && news.getPriority() == 4) {
                broadcastNews(news);
            }
            
            log.info("新闻推送成功：{}", news.getTitle());
            return true;
        } catch (Exception e) {
            log.error("新闻推送失败：{}", news.getTitle(), e);
            return false;
        }
    }

    @Override
    public Boolean pushNewsToUser(String userId, News news) {
        try {
            NewsVO newsVO = convertToVO(news);
            newsWebSocketHandler.pushNewsToUser(userId, newsVO);
            log.debug("推送新闻给用户：{} -> {}", userId, news.getTitle());
            return true;
        } catch (Exception e) {
            log.error("推送新闻给用户失败：{} -> {}", userId, news.getTitle(), e);
            return false;
        }
    }

    @Override
    public Boolean pushNewsToCategory(String categoryId, News news) {
        try {
            NewsVO newsVO = convertToVO(news);
            newsWebSocketHandler.pushNewsToCategory(categoryId, newsVO);
            log.debug("推送新闻给分类订阅者：{} -> {}", categoryId, news.getTitle());
            return true;
        } catch (Exception e) {
            log.error("推送新闻给分类订阅者失败：{} -> {}", categoryId, news.getTitle(), e);
            return false;
        }
    }

    @Override
    public Boolean pushNewsToTag(String tag, News news) {
        try {
            NewsVO newsVO = convertToVO(news);
            newsWebSocketHandler.pushNewsToTag(tag, newsVO);
            log.debug("推送新闻给标签订阅者：{} -> {}", tag, news.getTitle());
            return true;
        } catch (Exception e) {
            log.error("推送新闻给标签订阅者失败：{} -> {}", tag, news.getTitle(), e);
            return false;
        }
    }

    @Override
    public Boolean broadcastNews(News news) {
        try {
            NewsVO newsVO = convertToVO(news);
            newsWebSocketHandler.broadcastNews(newsVO);
            log.info("广播新闻给所有用户：{}", news.getTitle());
            return true;
        } catch (Exception e) {
            log.error("广播新闻失败：{}", news.getTitle(), e);
            return false;
        }
    }

    /**
     * 根据标签推送新闻
     */
    private void pushNewsByTags(News news) {
        try {
            @SuppressWarnings("unchecked")
            List<String> tags = objectMapper.readValue(news.getTags(), List.class);
            for (String tag : tags) {
                pushNewsToTag(tag, news);
            }
        } catch (JsonProcessingException e) {
            log.error("解析新闻标签失败：{}", news.getTags(), e);
        }
    }

    /**
     * 转换为VO
     */
    @SuppressWarnings("deprecation")
    private NewsVO convertToVO(News news) {
        NewsVO vo = BeanCopyUtils.copyBean(news, NewsVO.class);
        
        // 设置基本信息
        if (news.getType() != null) {
            vo.setTypeName(getTypeName(news.getType()));
        }
        if (news.getStatus() != null) {
            vo.setStatusName(getStatusName(news.getStatus()));
        }
        if (news.getPriority() != null) {
            vo.setPriorityName(getPriorityName(news.getPriority()));
        }
        
        return vo;
    }

    private String getTypeName(Integer type) {
        return switch (type) {
            case 1 -> "原创";
            case 2 -> "转载";
            case 3 -> "爬虫";
            default -> "未知";
        };
    }

    private String getStatusName(Integer status) {
        return switch (status) {
            case 0 -> "草稿";
            case 1 -> "已发布";
            case 2 -> "已下架";
            case 3 -> "审核中";
            case 4 -> "审核失败";
            default -> "未知";
        };
    }

    private String getPriorityName(Integer priority) {
        return switch (priority) {
            case 1 -> "低";
            case 2 -> "中";
            case 3 -> "高";
            case 4 -> "紧急";
            default -> "未知";
        };
    }
}
